import 'package:easy_refresh/easy_refresh.dart';
import 'package:flutter/material.dart';

import 'package:junyeyishu/utils/utils.dart';
import 'package:junyeyishu/widgets/QGEmpty.dart';

abstract class QGCacheListState<T extends StatefulWidget> extends State<T> {
  String? tabURL;
  String tabKey = "data";
  dynamic tab;

  String? listURL;
  String listKey = "data";
  dynamic list;

  dynamic temp;

  SliverGridDelegate? gridDelegate;

  Map<String, dynamic> tabParam() {
    return <String, dynamic>{};
  }

  Map<String, dynamic> listParam() {
    return <String, dynamic>{};
  }

  onUpdateTab(data) {}
  onUpdateList(data) {}

  canUpdateList(data) {
    return true;
  }

  Widget itemBuilder(context, index, dynamic data) {
    return Container();
  }

  // #########

  int page = 1;
  var refreshController = EasyRefreshController(
      controlFinishRefresh: true, controlFinishLoad: true);

  Widget _buildItem(context, index) {
    if (list is List && list.length > index) {
      return itemBuilder(context, index, list[index]);
    }
    return Container();
  }

  buildList() {
    if (list == null) {
      return Expanded(
          child: Center(
              child: CircularProgressIndicator(color: Color(0xFF000000))));
    }

    if (list is! List || list.isEmpty) {
      return QGEmpty(isExpanded: true);
    }

    return Expanded(
      child: EasyRefresh(
          controller: refreshController,
          onLoad: onLoad,
          onRefresh: onRefresh,
          child: gridDelegate == null
              ? ListView.builder(
                  padding: EdgeInsets.zero,
                  itemCount: list is List ? list.length : 0,
                  itemBuilder: _buildItem)
              : GridView.builder(
                  gridDelegate: gridDelegate!,
                  padding: EdgeInsets.all(15.rpx),
                  itemCount: list is List ? list.length : 0,
                  itemBuilder: _buildItem)),
    );
  }

  loadTab() {
    if (tabURL != null) {
      Network.get(tabURL, tabParam()).then((res) {
        if (!res.success) {
          toast(res.msg);
          return;
        }

        if (res.data is List) {
          tab = res.data;
        } else if (res.data is Map) {
          tab = res.data[tabKey];
        }

        onUpdateTab(tab);

        if (mounted) {
          setState(() {});
        }
      });
    }
  }

  onRefresh() {
    if (listURL == null) return;

    page = 1;

    var param = listParam();
    param["page"] = page;

    Network.get(listURL, param).then((res) {
      if (!res.success) {
        toast(res.msg);
        list = [];
        setState(() {});
        return;
      }

      onResponse(res);

      if (res.data is String) {
        res.data = decryptToJson(res.data);
      }

      res.data = resetData(res.data);

      if (res.data is List) {
        if (!canUpdateList(res.data ?? [])) {
          refreshController.finishRefresh();
          refreshController.finishLoad();
          return;
        }
        list = res.data ?? [];
      } else if (res.data is Map) {
        if (!canUpdateList(res.data[listKey] ?? [])) {
          refreshController.finishRefresh();
          refreshController.finishLoad();
          return;
        }
        list = res.data[listKey] ?? [];
      }

      var allnum = 0;

      if (res.data is List) {
        allnum = int.parse("${res.ret?["allnum"] ?? "0"}");
      } else if (res.data is Map) {
        allnum = int.parse("${res.data?["allnum"] ?? "0"}");
      }

      refreshController.finishRefresh();
      refreshController.finishLoad();

      if (list is List && list.length >= allnum) {
        refreshController.finishLoad(IndicatorResult.noMore);
      }
      onUpdateList(list);

      if (mounted) {
        setState(() {});
      }
    });
  }

  onLoad() {
    if (listURL == null) return;

    var param = listParam();
    param["page"] = ++page;

    Network.get(listURL, param).then((res) {
      if (!res.success) {
        toast(res.msg);
        page -= 1;
        refreshController.finishLoad(IndicatorResult.fail);
        return;
      }

      if (res.data is String) {
        res.data = decryptToJson(res.data);
      }

      res.data = resetData(res.data);

      if (res.data is List) {
        temp = res.data ?? [];
      } else if (res.data is Map) {
        if (res.data[listKey] is List) {
          temp = res.data[listKey] ?? [];
        } else if (res.data[listKey] is Map) {
          temp = [];
        }
      }

      var allnum = 0;

      if (res.data is List) {
        allnum = int.parse("${res.ret?["allnum"] ?? "0"}");
      } else if (res.data is Map) {
        allnum = int.parse("${res.data?["allnum"] ?? "0"}");
      }

      list.addAll(temp);

      if (list.length >= allnum) {
        refreshController.finishLoad(IndicatorResult.noMore);
      } else {
        refreshController.finishLoad();
      }

      onUpdateList(list);
      if (mounted) setState(() {});
    });
  }

  resetData(data) {
    return data;
  }

  onResponse(res) {}
}
